//-----------------------------------------------------------------------------
//  Copyright (c) 2013 by HangZhou HenqgQiao Design Corporation. All rights reserved.
//
//  Project  : 
//  Module   : over sample the input data with 8-phases 311M clock
//  Parent   : 
//  Children : 
//
//  Description: 
//
//  Parameters:
//  Local Parameters:
//
//  Notes       : 
//
//  Multicycle and False Paths

module FRM_TFRM(
   input                         FRM_RESET,
   input                         FRM_TXCLK,

   input                         GLBCF_LINF_MODE,

   input[1:0]                    TFRM_IN_FMCNT4,
   input[8:0]                    TFRM_IN_FMCNT270,
   input[3:0]                    TFRM_IN_FMCNT9,
   input[7:0]                    TFRM_IN_DATA,

   output reg[7:0]               TFRM_OUT_DATA
   );

reg                              FRMBD_LINF_MODE;
wire[1:0]                        FRMBD_FMCNT4;
wire[8:0]                        FRMBD_FMCNT270;
wire[3:0]                        FRMBD_FMCNT9;
wire[7:0]                        FRMBD_DATA;
reg[7:0]                         FRMBD_SCRM_VECTOR;
reg                              FRMBD_SCRM_EN;
wire[7:0]                        FRMBD_B1_RESULT;

reg[1:0]                         FRMBD_OUT_FMCNT4;
reg[8:0]                         FRMBD_OUT_FMCNT270;
reg[3:0]                         FRMBD_OUT_FMCNT9;
reg[7:0]                         FRMBD_OUT_DATA;

reg[7:0]                         B1_CALCULATING;
reg[7:0]                         B1_RESULT;





  assign FRMBD_FMCNT4[1:0]        = TFRM_IN_FMCNT4[1:0];
  assign FRMBD_FMCNT270[8:0]      = TFRM_IN_FMCNT270[8:0];
  assign FRMBD_FMCNT9[3:0]        = TFRM_IN_FMCNT9[3:0];
  assign FRMBD_DATA[7:0]          = TFRM_IN_DATA[7:0];
  assign FRMBD_B1_RESULT[7:0]     = B1_RESULT[7:0];

always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      FRMBD_LINF_MODE                                     <= 1'b0;
   else
      FRMBD_LINF_MODE                                     <= GLBCF_LINF_MODE;
end

always @( FRMBD_FMCNT270 or FRMBD_FMCNT9 or FRMBD_LINF_MODE or FRMBD_FMCNT4) begin
   if ( FRMBD_LINF_MODE==1'b1 ) begin
      if ( FRMBD_FMCNT270[8:0] <9'd9 && FRMBD_FMCNT9[3:0]==4'd0 )
         FRMBD_SCRM_EN                                    <= 1'b0;
      else
         FRMBD_SCRM_EN                                    <= 1'b1;
   end
   else begin
      if ( FRMBD_FMCNT270[8:0] <9'd9 && FRMBD_FMCNT9[3:0]==4'd0 )
         FRMBD_SCRM_EN                                    <= 1'b0;
      else if ( FRMBD_FMCNT4[1:0]==2'd3 )
         FRMBD_SCRM_EN                                    <= 1'b1;
      else
         FRMBD_SCRM_EN                                    <= 1'b0;
   end
end

always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      FRMBD_SCRM_VECTOR[7:0]                              <= 8'd0;
   else begin
      if ( FRMBD_FMCNT4[1:0]==2'd3 && FRMBD_FMCNT270[8:0]==9'd269 && FRMBD_FMCNT9[3:0]==4'd8)
         FRMBD_SCRM_VECTOR[7:0]                           <= 8'hfe;
      else if ( FRMBD_SCRM_EN==1'b1) begin
         FRMBD_SCRM_VECTOR[7]                             <= FRMBD_SCRM_VECTOR[6] ^ FRMBD_SCRM_VECTOR[5];
         FRMBD_SCRM_VECTOR[6]                             <= FRMBD_SCRM_VECTOR[5] ^ FRMBD_SCRM_VECTOR[4];
         FRMBD_SCRM_VECTOR[5]                             <= FRMBD_SCRM_VECTOR[4] ^ FRMBD_SCRM_VECTOR[3];
         FRMBD_SCRM_VECTOR[4]                             <= FRMBD_SCRM_VECTOR[3] ^ FRMBD_SCRM_VECTOR[2];
         FRMBD_SCRM_VECTOR[3]                             <= FRMBD_SCRM_VECTOR[2] ^ FRMBD_SCRM_VECTOR[1];
         FRMBD_SCRM_VECTOR[2]                             <= FRMBD_SCRM_VECTOR[1] ^ FRMBD_SCRM_VECTOR[0];
         FRMBD_SCRM_VECTOR[1]                             <= FRMBD_SCRM_VECTOR[0] ^ (FRMBD_SCRM_VECTOR[6] ^ FRMBD_SCRM_VECTOR[5]);
         FRMBD_SCRM_VECTOR[0]                             <= (FRMBD_SCRM_VECTOR[6] ^ FRMBD_SCRM_VECTOR[5]) ^ (FRMBD_SCRM_VECTOR[5] ^ FRMBD_SCRM_VECTOR[4]);
      end
   end
end

always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 ) begin
      FRMBD_OUT_FMCNT4[1:0]                               <= 2'd0;
      FRMBD_OUT_FMCNT270[8:0]                             <= 9'd0;
      FRMBD_OUT_FMCNT9[3:0]                               <= 4'd0;
   end
   else begin
      FRMBD_OUT_FMCNT4[1:0]                               <= FRMBD_FMCNT4[1:0];
      FRMBD_OUT_FMCNT270[8:0]                             <= FRMBD_FMCNT270[8:0];
      FRMBD_OUT_FMCNT9[3:0]                               <= FRMBD_FMCNT9[3:0];
   end
end

always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      FRMBD_OUT_DATA[7:0]                                 <= 8'd0;
   else begin
      if ( FRMBD_FMCNT9[3:0]==4'd0 && (FRMBD_FMCNT270[8:0]==9'd0 || FRMBD_FMCNT270[8:0]==9'd1 || FRMBD_FMCNT270[8:0]==9'd2) )
         FRMBD_OUT_DATA[7:0]                              <= 8'hf6;
      else if ( FRMBD_FMCNT9[3:0]==4'd0 && (FRMBD_FMCNT270[8:0]==9'd3 || FRMBD_FMCNT270[8:0]==9'd4 || FRMBD_FMCNT270[8:0]==9'd5) )
         FRMBD_OUT_DATA[7:0]                              <= 8'h28;
      else if ( FRMBD_FMCNT9[3:0]==4'd0 && (FRMBD_FMCNT270[8:0]==9'd7 || FRMBD_FMCNT270[8:0]==9'd8) )
         FRMBD_OUT_DATA[7:0]                              <= 8'h55;
      else if ( FRMBD_FMCNT9[3:0]==4'd1 && FRMBD_FMCNT270[8:0]==9'd0 && FRMBD_FMCNT4[1:0]==2'd0 && FRMBD_LINF_MODE==1'b1 )
         FRMBD_OUT_DATA[7:0]                              <= FRMBD_B1_RESULT[7:0] ^ FRMBD_SCRM_VECTOR[7:0];
      else if ( FRMBD_FMCNT9[3:0]==4'd1 && FRMBD_FMCNT270[8:0]==9'd0 && FRMBD_LINF_MODE==1'b0 )
         FRMBD_OUT_DATA[7:0]                              <= FRMBD_B1_RESULT[7:0] ^ FRMBD_SCRM_VECTOR[7:0];
      else
         FRMBD_OUT_DATA[7:0]                              <= FRMBD_DATA[7:0] ^ FRMBD_SCRM_VECTOR[7:0];
   end
end


always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      B1_CALCULATING[7:0]                           <= 8'd0;
   else begin
      if ( FRMBD_OUT_FMCNT4[1:0]==2'd3 && FRMBD_OUT_FMCNT270[8:0]==9'd269 && FRMBD_OUT_FMCNT9[3:0]==4'd8 )
         B1_CALCULATING[7:0]                        <= 8'd0;
      else begin
         if ( FRMBD_LINF_MODE==1'b1 )
            B1_CALCULATING[7:0]                     <= B1_CALCULATING[7:0] ^ FRMBD_OUT_DATA[7:0];
         else begin
            if ( FRMBD_OUT_FMCNT4[1:0]==2'd3 )
               B1_CALCULATING[7:0]                  <= B1_CALCULATING[7:0] ^ FRMBD_OUT_DATA[7:0];
         end
      end
   end
end

always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      B1_RESULT[7:0]                                <= 8'd0;
   else begin
      if ( FRMBD_OUT_FMCNT4[1:0]==2'd3 && FRMBD_OUT_FMCNT270[8:0]==9'd269 && FRMBD_OUT_FMCNT9[3:0]==4'd8 )
         B1_RESULT[7:0]                             <= B1_CALCULATING[7:0] ^ FRMBD_OUT_DATA[7:0];
   end
end


// output bit interleave by line interface mode
always @( posedge FRM_RESET or posedge FRM_TXCLK ) begin
   if ( FRM_RESET==1'b1 )
      TFRM_OUT_DATA[7:0]                            <= 8'd0;
   else begin
      if ( FRMBD_LINF_MODE==1'b1 )
         TFRM_OUT_DATA[7:0]                         <= FRMBD_OUT_DATA[7:0];
      else begin
         case ( FRMBD_OUT_FMCNT4[1:0] )
         2'd0: TFRM_OUT_DATA[7:0]                   <= {FRMBD_OUT_DATA[7], FRMBD_OUT_DATA[7], FRMBD_OUT_DATA[7], FRMBD_OUT_DATA[7], FRMBD_OUT_DATA[6], FRMBD_OUT_DATA[6], FRMBD_OUT_DATA[6], FRMBD_OUT_DATA[6]};
         2'd1: TFRM_OUT_DATA[7:0]                   <= {FRMBD_OUT_DATA[5], FRMBD_OUT_DATA[5], FRMBD_OUT_DATA[5], FRMBD_OUT_DATA[5], FRMBD_OUT_DATA[4], FRMBD_OUT_DATA[4], FRMBD_OUT_DATA[4], FRMBD_OUT_DATA[4]};
         2'd2: TFRM_OUT_DATA[7:0]                   <= {FRMBD_OUT_DATA[3], FRMBD_OUT_DATA[3], FRMBD_OUT_DATA[3], FRMBD_OUT_DATA[3], FRMBD_OUT_DATA[2], FRMBD_OUT_DATA[2], FRMBD_OUT_DATA[2], FRMBD_OUT_DATA[2]};
         2'd3: TFRM_OUT_DATA[7:0]                   <= {FRMBD_OUT_DATA[1], FRMBD_OUT_DATA[1], FRMBD_OUT_DATA[1], FRMBD_OUT_DATA[1], FRMBD_OUT_DATA[0], FRMBD_OUT_DATA[0], FRMBD_OUT_DATA[0], FRMBD_OUT_DATA[0]};
         default: ;
         endcase
      end
   end
end



endmodule
